App.require(["htmlTool"], function (htmlTool) {
    var app = App.getCurrent();
    app.defineComponent("str-card", {
        render: function (next) {
            this.computedData();
            this.fetch("./index.html", function (text) {
                return next(this.renderHTML(text));
            })
        },
        getDomObj: function () {
            this.attachDom('[role="card"]', "container")
                .attachEvent("container", "btnclick", this.btnClickHandler, false)
                .attachEvent("container", "iconclick", this.iconClickHandler, false)
                .attachDom(".card-media", "media");

            if (this.domList.media) {
                this.attachEvent("media", "click", this.clickMediaHandler, false);
            }
        },
        createSlotList: function (str) {
            var list = str.split(/;\s*/g);
            var result = [];
            for (var i = 0; i < list.length; i++) {
                result.push({
                    name: list[i]
                });
            }
            return result;
        },
        appendOption: function (value, content, type, feeback) {
            var html = "", container = this.domList.container, that = this;
            var result = {
                value: value,
                content: content,
                type: type
            };
            if (type == "btn") {
                html = '<str-btn rendertype="link" id="' + value+ '">' + content + '</str-btn>';
                var btnContainer = container.querySelector(".card-btn-container");
                this.insertAdjacentHTML(btnContainer, html, "beforeend", function () {
                    that.data.options.push(result);
                    that.data.buttons.push(result);
                    if (typeof feeback === "function") feeback();
                })
            }
            else {
                html = '<str-icon class="ripple" role="icon" icon="' + value + '" width="24" height="24" id="' + value + '">';
                var iconContainer = container.querySelector(".card-icons-container");
                this.insertAdjacentHTML(iconContainer, html, "beforeend", function () {
                    that.data.options.push(result);
                    that.data.icons.push(result);
                    if (typeof feeback === "function") feeback();
                })
            }
        },
        _getOptionByValue: function (value) {
            var options = this.data.options, result = null;

            for (var i = 0; i < options.length; i++) {
                if (options[i].value === value) return options[i];
            }
            return result;
        },
        _getIndexByValue: function (list, value) {
            var index = -1;
            for (var i = 0; i < list.length; i++) {
                if (list[i].value === value) {
                    index = i;
                    break;
                }
            }
            return index;
        },
        removeOption: function (value) {
            var option = this._getOptionByValue(value), targetList;
            if (!option) return false;
            if (option.type === "btn") targetList = this.data.buttons;
            else targetList = this.data.icons;

            var index = this._getIndexByValue(targetList, value);
            if (index !== -1) {
                targetList.splice(index, 1);
                var optionIndex = this._getIndexByValue(this.data.options, value);
                this.data.options.splice(optionIndex, 1);
                var components = this.components;
                for (var i = 0; i < components.length; i++) {
                    if (components[i].id === value) {
                        this.removeComponent(components[i]);
                        break;
                    }
                }
            }
        },
        insertBefore: function (oldValue, value, content, feeback) {
            var html = "", container = this.domList.container, that = this;
            var option = this._getOptionByValue(oldValue);
            if (!option) return false;
            var type = option.type, index, targetList, targetDom;
            if (type === "btn") {
                targetList = this.data.buttons;
                targetDom = container.querySelector(".card-btn-container");
                html = '<str-btn rendertype="link" id="' + value+ '">' + content + '</str-btn>';
            }
            else {
                targetList = this.data.icons;
                targetDom =  container.querySelector(".card-icons-container");
                html = '<str-icon class="ripple" role="icon" icon="' + value + '" width="24" height="24" id="' + value + '">';
            }
            index = this._getIndexByValue(targetList, oldValue);
            var optionIndex = this._getIndexByValue(this.data.options, oldValue);
            if (index === -1) return false;
            var result = {
                value: value,
                content: content,
                type: type
            };
            var component = this._getComponentByValue(oldValue);
            this.insertAdjacentHTML(component.nodes[0], html, "beforebegin", function () {
                that.data.options.splice(optionIndex, 0, result);
                targetList.splice(index, 0, result);
                if (typeof feeback === "function") feeback();
            })
        },
        _getComponentByValue: function (value) {
            var components = this.components;
            for (var i = 0; i < components.length; i++) {
                if (components[i].id === value) return components[i];
            }
            return null;
        },
        computedData: function () {
            var property = this.property;
            property.slotlist = property.slotlist || "header;media;support";
            this.data.needSlots = this.createSlotList(property.slotlist);
            property.thumbnail = property.thumbnail || "";
            property.media = property.media || "";
            property.header = property.header || "";
            property.subheader = property.subheader  || "";
            property.support = property.support || "";

            this.data.options = htmlTool.getOptions(this.slot);
            this.splitAction(this.data.options);
            property.class = property.class || "";
            this.data.propertystr = this.createPropertyStr({
                class: property.class
            });
        },
        get media() {
            return this.property.media;
        },
        set media(value) {
            if (value === this.property.media || !this.property.media) return;
            var slot = this.getSlotByName("media");
            if (slot.isOrigin) {
                var cardDetail = this.domList.container.querySelector(".str-card-detail");
                if (this.property.media) {
                    if (value) {
                        var img = cardDetail.querySelector("img");
                        if (img) img.src = value;
                    }
                    else {
                        cardDetail.removeChild(cardDetail.firstElementChild);
                    }
                }
                else {
                    var div = document.createElement("div");
                    div.className = "card-media ripple";
                    var img = document.createElement("img");
                    img.src = value;
                    div.appendChild(img);
                    cardDetail.insertBefore(div, cardDetail.firstElementChild);
                }
                this.property.media = value;
            }
        },
        get thumbnail() {
            return this.property.thumbnail;
        },
        set thumbnail(value) {
            if (value === this.property.thumbnail) return;
            var slot = this.getSlotByName("header");
            if (this.property.header && slot.isOrigin) {
                var cardDiv = this.domList.container.querySelector(".card-header");
                if (this.property.thumbnail) {
                    var img = cardDiv.firstElementChild;
                    if (value) {
                        img.src = value;
                    }
                    else {
                        cardDiv.removeChild(img);
                    }
                }
                else {
                    var img = document.createElement("img");
                    img.src = value;
                    cardDiv.insertBefore(img, cardDiv.firstElementChild);
                }
            }
            this.property.thumbnail = value;
        },
        get header() {
            return this.property.header;
        },
        set header(value) {
            if (value === this.property.header) return;
            var slot = this.getSlotByName("header");
            if (slot.isOrigin && this.property.header) {
                var div = document.createElement("div");
                div.className = "card-header";
                if (this.property.thumbnail) {
                    var img = document.createElement("img");
                    img.src = this.property.thumbnail;
                    div.appendChild(img);
                }
                var headerDiv = document.createElement("div");
                headerDiv.className = "header-container";
                var h = document.createElement("h3");
                h.textContent = value;
                headerDiv.appendChild(h);
                if (this.property.subheader) {
                    var d = document.createElement("div");
                    d.textContent = this.property.subheader;
                    headerDiv.appendChild(d);
                }
                div.appendChild(headerDiv);
            }
            else {
                var h = this.domList.container.querySelector("header-container>h3");
                if (h) h.textContent = this.property.header;
            }
            this.property.subheader = value;
        },
        get subheader() {
            return this.property.subheader;
        },
        set subheader(value) {
            if (value === this.property.subheader) return;
            var slot = this.getSlotByName("header");
            if (slot.isOrigin && this.property.header) {
                var headContainer = this.domList.container.querySelector(".header-container");
                if (this.property.subheader) {
                    headContainer.children[1].textContent = value;
                }
                else {
                    var div = document.createElement("div");
                    div.textContent = value;
                    headContainer.appendChild(div);
                }
            }
            this.property.subheader = value;
        },
        get support() {
            return this.property.support;
        },
        set support(value) {
            if (value === this.property.support) return;
            var slot = this.getSlotByName("support");
            if (slot.isOrigin) {
                this.domList.container.querySelector(".support-text").textContent = value;
            }
            this.property.support = value;
        },
        get className() {
            return this.property.class;
        },
        set className(value) {
            if (value === this.property.class) return;
            this.domList.container.className = value;
            this.property.class = value;
        },
        splitAction: function (options) {
            this.data.icons = [];
            this.data.buttons = [];
            for (var i = 0; i < options.length; i++) {
                var option = options[i];
                if (option.type === "btn") this.data.buttons.push(option);
                else if (option.type === "icon") this.data.icons.push(option);
            }
        },
        computedList: function (nameList, actionList) {
            var nameLen = nameList.length, actionLen = actionList.length;
            var min = Math.min(nameLen, actionLen);
            var result = [];
            for (var i = 0; i < min; i++) {
                result.push({
                    name: nameList[i],
                    action: actionList[i]
                });
            }
            return result;
        },
        clickMediaHandler: function (ev) {
            this.dispatchCustomEvent("cardmediaclick", { component: this, target: ev.currentTarget });
        },
        btnClickHandler: function (ev) {
            this.handlerComponent(ev.detail.component);
        },
        iconClickHandler: function (ev) {
            this.handlerComponent(ev.detail.component);
        },
        handlerComponent: function (component) {
            var action = component.property.id;
            this.dispatchCustomEvent("cardactionclick", { component: this, target: component, action: action });
        }
    })
})